/* Copyright (c) 2021-2022 Huawei Device Co., Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: liangkz @ https://ost.51cto.com/column/46
 * Date  : 2022.04.01
 *
 */
#include "unistd.h"
//#include "stdlib.h"
//#include "stdio.h"

#include "light_if.h"
#include "hilog/log.h"

#undef  LOG_TAG
#undef  LOG_DOMAIN
#define LOG_TAG    "ledx"
#define LOG_DOMAIN 0xD002022

const struct LightInterface *g_lightDev = NULL;
static struct LightInfo *g_lightInfo = NULL;
static uint32_t g_lightCnt = 0;

#define LIGHT_MAKE_R_BIT    0x80000000
#define LIGHT_MAKE_G_BIT    0x00008000
#define LIGHT_MAKE_B_BIT    0x00000080

void ledSetBrt(int32_t idx, struct LightEffect *ef)
{
    //0BGR
    //0111:
    ef->lightBrightness = 0;
    if(idx&0x01)
        ef->lightBrightness |= LIGHT_MAKE_R_BIT;
    if(idx&0x02)
        ef->lightBrightness |= LIGHT_MAKE_G_BIT;
    if(idx&0x04)
        ef->lightBrightness |= LIGHT_MAKE_B_BIT; 
    
}

int main(int argc, char* argv[])
{
    int32_t  ret = -1;
    int32_t  idx = 0;
	int32_t  ledId  = 0;
	int32_t  ledMod = 0;
	int32_t  ledBrt = 0;

    struct LightEffect ef = {0};
    ef.flashEffect.flashMode = LIGHT_FLASH_NONE;
    ef.flashEffect.offTime   = 500;  //if flash, set Off 500ms
    ef.flashEffect.onTime    = 1000; //if flash, set On  1000ms
    ef.lightBrightness       = 0x00000000;

    g_lightDev = NewLightInterfaceInstance();
    if (g_lightDev == NULL) {
        HILOG_INFO(LOG_APP, "[%{public}s] main: g_lightDev is NULL, Exit.", LOG_TAG);
        return -1;
    }

	HILOG_INFO(LOG_APP, "[%{public}s] main Enter:", LOG_TAG);
	HILOG_INFO(LOG_APP, "    ledId [-1, 0, 1, 2]: -1-Exit, 0-GetLightInfo, 1-Led1, 2-Led2");
	HILOG_INFO(LOG_APP, "    ledMod[-1, 0, 1   ]: -1-Flash,0-Off, 1-On");
	HILOG_INFO(LOG_APP, "    ledBrt[ 1, 2, 4, x]:  1-R,    2-G,   4-B, x-bit");

    int32_t matrixId = 0;
    int32_t matrix[][3] = 
    {
        {0, 0, 0}, //GetLightInfo

        {1, 0, 4}, //LED1 Off all RGB
        {1, 1, 1}, //LED1 On R
        {1, 1, 2}, //LED1 On G
        {1, 1, 4}, //LED1 On B
        {1, 0, 0}, //LED1 Off
        {1, 1, 7}, //LED1 On BGR:111
        {1, 1, 6}, //LED1 On BG-:110
        {1, 1, 5}, //LED1 On B-R:101
        {1, 1, 4}, //LED1 On B--:100
        {1, 1, 3}, //LED1 On -GR:011
        {1, 1, 2}, //LED1 On -G-:010
        {1, 1, 1}, //LED1 On --R:001
        {1, 0, 0}, //LED1 Off
        {1, -1, 7}, //LED1 Flash RGB

        {-1, 0, 0},//Exit
    };

    while (1)
    {
        ledId  = matrix[matrixId][0];
        ledMod = matrix[matrixId][1];
        ledBrt = matrix[matrixId][2];

        HILOG_INFO(LOG_APP, "--------------------------------------------------------");
	    HILOG_INFO(LOG_APP, "matrixId[%{public}d]: ledId[%{public}d] ledMod[%{public}d] ledBrt[%{public}d]",
	           matrixId, ledId, ledMod, ledBrt);
        matrixId ++;

        switch (ledId)
        {
            case -1:
            {
                HILOG_INFO(LOG_APP, "[%{public}s] main Exit.", LOG_TAG);
                if (g_lightDev != NULL) {
                    for (idx=0; idx<g_lightCnt; idx++)
                        g_lightDev->TurnOffLight(g_lightInfo[idx].lightId);  //Off all Led
                    FreeLightInterfaceInstance();
                }
                return 0;
            }
            case 0:  //GetLedInfo
            {
                ret = g_lightDev->GetLightInfo(&g_lightInfo, &g_lightCnt);
                if (ret == -1) {
                    HILOG_INFO(LOG_APP, "GetLightInfo NG");
                } else {
                    HILOG_INFO(LOG_APP, "GetLightInfo OK: %{public}d-Light", g_lightCnt);
                }
                break;
            }
            case 1:  //Led1
            {
                for (idx=0; idx<g_lightCnt; idx++) {
                    g_lightDev->TurnOffLight(g_lightInfo[idx].lightId);  //Off all Led
                    usleep(50);
                }

                if (g_lightCnt < ledId) {
                    HILOG_INFO(LOG_APP, "Led1 NOT Exist");
                    break;
                }

                if (ledMod == 0) {  //Led1 Off
                    HILOG_INFO(LOG_APP, "Led1: Off");
                    g_lightDev->TurnOffLight(g_lightInfo[0].lightId);
                } else if (ledMod == 1) {  //Led1 ON
                    ledSetBrt(ledBrt, &ef);
                    HILOG_INFO(LOG_APP, "Led1: ON, lightBrightness[0x%{public}08X]", ef.lightBrightness);
                    g_lightDev->TurnOnLight(g_lightInfo[0].lightId, &ef);
                } else if (ledMod == -1) {  //Led1 Flash
                    ef.flashEffect.flashMode = LIGHT_FLASH_TIMED;
                    ledSetBrt(ledBrt, &ef);
                    HILOG_INFO(LOG_APP, "Led1: Flash Mode, lightBrightness[0x%{public}08X]", ef.lightBrightness);
                    g_lightDev->TurnOnLight(g_lightInfo[0].lightId, &ef);
                    sleep(10);
                } else {
                    HILOG_INFO(LOG_APP, "Led1: ledMod Invalid");
                }
                break;
            }            
            case 2:  //Led2
            {
                HILOG_INFO(LOG_APP, "led2 NO ops");
                break;
            }
            default:
            {
                HILOG_INFO(LOG_APP, "ledId Invalid");
                break;
            }
        }

        sleep(3);
    }

	HILOG_INFO(LOG_APP, "[%{public}s] main Exit.", LOG_TAG);
    return 0;
}
